/**
 * 小车控制工具类
 * 通过WebSocket连接到控制服务器发送控制指令
 */

const WS_SERVER_URL = 'ws://8.130.109.229:8765/app'

// 小车控制命令映射
export const CAR_COMMANDS = {
  forward: '$QJ!',      // 前进
  backward: '$HT!',     // 后退
  left: '$ZZ!',         // 左转
  right: '$YZ!',        // 右转
  leftSlide: '$ZPY!',   // 左平移
  rightSlide: '$YPY!',  // 右平移
  stop: '$TZ!',         // 停止
  track: '$ZNXJ!',      // 智能循迹
  avoid: '$ZYBZ!',      // 自由避障
  follow: '$GSGN!'      // 定距跟随
}

// 云台控制命令生成
export const generateServoCommand = (index, pwm, time = 1000) => {
  // 格式: #IndexPpwmTtime!
  // Index: 000-254, pwm: 0500-2500, time: 0000-9999
  const indexStr = String(index).padStart(3, '0')
  const pwmStr = String(pwm).padStart(4, '0')
  const timeStr = String(time).padStart(4, '0')
  return `#${indexStr}P${pwmStr}T${timeStr}!`
}

// 速度设置命令生成
export const generateSpeedCommand = (speed1, speed2, speed3, speed4) => {
  // 格式: $Car:speed1,speed2,speed3,speed4!
  return `$Car:${speed1},${speed2},${speed3},${speed4}!`
}

class CarControlClient {
  constructor() {
    this.ws = null
    this.reconnectAttempts = 0
    this.maxReconnectAttempts = 5
    this.reconnectDelay = 3000
    this.isConnected = false
    this.listeners = new Map()
  }

  /**
   * 连接到控制服务器
   */
  connect() {
    return new Promise((resolve, reject) => {
      try {
        console.log('🔌 正在连接到控制服务器:', WS_SERVER_URL)
        this.ws = new WebSocket(WS_SERVER_URL)

        this.ws.onopen = () => {
          console.log('✅ 已连接到控制服务器')
          this.isConnected = true
          this.reconnectAttempts = 0
          this.emit('connected')
          resolve()
        }

        this.ws.onmessage = (event) => {
          try {
            const data = JSON.parse(event.data)
            console.log('📨 收到服务器消息:', data)
            this.emit('message', data)
          } catch (error) {
            console.error('解析消息失败:', error)
          }
        }

        this.ws.onerror = (error) => {
          console.error('❌ WebSocket错误:', error)
          this.emit('error', error)
          reject(error)
        }

        this.ws.onclose = () => {
          console.log('🔌 连接已关闭')
          this.isConnected = false
          this.emit('disconnected')
          
          // 自动重连
          if (this.reconnectAttempts < this.maxReconnectAttempts) {
            this.reconnectAttempts++
            console.log(`🔄 ${this.reconnectDelay/1000}秒后尝试重连 (${this.reconnectAttempts}/${this.maxReconnectAttempts})...`)
            setTimeout(() => {
              this.connect().catch(err => console.error('重连失败:', err))
            }, this.reconnectDelay)
          } else {
            console.error('❌ 达到最大重连次数，停止重连')
          }
        }
      } catch (error) {
        console.error('创建WebSocket连接失败:', error)
        reject(error)
      }
    })
  }

  /**
   * 发送控制命令
   */
  sendCommand(command, action = '') {
    if (!this.isConnected || !this.ws || this.ws.readyState !== WebSocket.OPEN) {
      console.error('❌ WebSocket未连接，无法发送命令')
      return Promise.reject(new Error('WebSocket未连接'))
    }

    const message = {
      type: 'command',
      command: command,
      action: action || command
    }

    return new Promise((resolve, reject) => {
      try {
        this.ws.send(JSON.stringify(message))
        console.log('📤 发送控制命令:', message)
        resolve(message)
      } catch (error) {
        console.error('发送命令失败:', error)
        reject(error)
      }
    })
  }

  /**
   * 控制小车移动
   */
  async controlCar(action) {
    const command = CAR_COMMANDS[action]
    if (!command) {
      console.error('未知的小车控制动作:', action)
      return Promise.reject(new Error(`未知的控制动作: ${action}`))
    }
    return this.sendCommand(command, action)
  }

  /**
   * 设置小车速度
   */
  async setSpeed(speed1, speed2, speed3, speed4) {
    const command = generateSpeedCommand(speed1, speed2, speed3, speed4)
    return this.sendCommand(command, 'setSpeed')
  }

  /**
   * 控制云台舵机
   */
  async controlServo(index, pwm, time = 1000) {
    const command = generateServoCommand(index, pwm, time)
    return this.sendCommand(command, 'controlServo')
  }

  /**
   * 停止所有舵机
   */
  async stopAllServos() {
    // 发送停止命令给所有常用舵机（0-3）
    const promises = []
    for (let i = 0; i < 4; i++) {
      promises.push(this.controlServo(i, 1500, 0)) // 1500是中间位置，time=0表示停止
    }
    return Promise.all(promises)
  }

  /**
   * 断开连接
   */
  disconnect() {
    if (this.ws) {
      this.ws.close()
      this.ws = null
    }
    this.isConnected = false
  }

  /**
   * 事件监听
   */
  on(event, callback) {
    if (!this.listeners.has(event)) {
      this.listeners.set(event, [])
    }
    this.listeners.get(event).push(callback)
  }

  /**
   * 移除事件监听
   */
  off(event, callback) {
    if (this.listeners.has(event)) {
      const callbacks = this.listeners.get(event)
      const index = callbacks.indexOf(callback)
      if (index > -1) {
        callbacks.splice(index, 1)
      }
    }
  }

  /**
   * 触发事件
   */
  emit(event, data) {
    if (this.listeners.has(event)) {
      this.listeners.get(event).forEach(callback => {
        try {
          callback(data)
        } catch (error) {
          console.error('事件回调执行失败:', error)
        }
      })
    }
  }
}

// 创建单例
let carControlInstance = null

export const getCarControlClient = () => {
  if (!carControlInstance) {
    carControlInstance = new CarControlClient()
  }
  return carControlInstance
}

export default getCarControlClient

